/*
 ** Caramel - Non-GUI Java Addons
 ** Copyright (c) 2001, 2002, 2003 by Gerald Bauer
 **
 ** This program is free software.
 **
 ** You may redistribute it and/or modify it under the terms of the GNU
 ** Lesser General Public License as published by the Free Software Foundation.
 ** Version 2.1 of the license should be included with this distribution in
 ** the file LICENSE, as well as License.html. If the license is not
 ** included with this distribution, you may find a copy at the FSF web
 ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
 ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
 **
 ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
 ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
 ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
 ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
 ** REDISTRIBUTION OF THIS SOFTWARE.
 **
 */

package kku.cs.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.logging.Logger;

public class ClassUtils {
	static Logger T = Logger.getLogger(ClassUtils.class.getName());

	public static String getJarFileName(Class clazz) {
		String className = clazz.getName();
		T.info("className=" + className);

		className = className.replace('.', '/');

		T.info("className=" + className);
		className += ".class";
		T.info("className=" + className);

		URL jarUrl = clazz.getClassLoader().getResource(className);

		String jarUrlString = jarUrl.toExternalForm();

		T.info("jarUrlString=" + jarUrlString);

		int from = "jar:file:".length();
		int to = jarUrlString.indexOf("!/");

		return jarUrlString.substring(from, to);
	}

	public static Object getProperty(Object obj, String propName) {
		String prop = "get" + propName.substring(0, 1).toUpperCase()
				+ propName.substring(1);
		Class empty[] = {};
		Object emptyparam[] = {};
		Method m;
		try {
			m = obj.getClass().getMethod(prop, empty);
			return m.invoke(obj, emptyparam);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static double getDouble(Object obj, String propName) {
		String prop = "get" + propName.substring(0, 1).toUpperCase()
				+ propName.substring(1);
		Class empty[] = {};
		Object emptyparam[] = {};
		Method m;
		try {
			m = obj.getClass().getMethod(prop, empty);
			return Converter.ObjToDouble(m.invoke(obj, emptyparam));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}
	public static float getFloat(Object obj, String propName) {
		String prop = "get" + propName.substring(0, 1).toUpperCase()
				+ propName.substring(1);
		Class empty[] = {};
		Object emptyparam[] = {};
		Method m;
		try {
			m = obj.getClass().getMethod(prop, empty);
			return Converter.ObjToFloat(m.invoke(obj, emptyparam));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	public static void setProperty(Object obj, String propName, String value) {
		String prop = "set" + propName.substring(0, 1).toUpperCase()
				+ propName.substring(1);
		Method setMethod = null;
		Method[] ms = obj.getClass().getMethods();
		for (int i = 0; i < ms.length; i++) {
			Method m = ms[i];
			if (m.getName().equals(prop)) {
				setMethod = m;
				break;
			}
		}
		if (setMethod == null)
			return;
		Class[] parameterTypes = setMethod.getParameterTypes();
		Object objValue = value;
		if (parameterTypes[0].equals(int.class)) {
			objValue = new Integer(Converter.ObjToInt(value));
		} else if (parameterTypes[0].equals(double.class)) {
			objValue = new Double(Converter.ObjToDouble(value));
		} else if (parameterTypes[0].equals(boolean.class)) {
			objValue = new Boolean(Converter.ObjToBoolean(value));
		}

		Object params[] = { objValue };
		try {
			// System.out.println("call
			// "+prop+"("+objValue+")"+parameterTypes[0]);
			setMethod.invoke(obj, params);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	public static void setProperty(Object obj, String propName, double value) {
		String prop = "set" + propName.substring(0, 1).toUpperCase()
				+ propName.substring(1);
		Method setMethod = null;
		Method[] ms = obj.getClass().getMethods();
		for (int i = 0; i < ms.length; i++) {
			Method m = ms[i];
			if (m.getName().equals(prop)) {
				setMethod = m;
				break;
			}
		}
		if (setMethod == null)
			return;
		Class[] parameterTypes = setMethod.getParameterTypes();
		Object objValue = new Double(value);
		if (parameterTypes[0].equals(int.class)) {
			objValue = new Integer((int) Math.round(value));
		} else if (parameterTypes[0].equals(double.class)) {
			objValue = new Double(value);
		} else if (parameterTypes[0].equals(float.class)) {
			objValue = new Float(value);
		} else if (parameterTypes[0].equals(boolean.class)) {
			objValue = new Boolean(value > 0);
		}
		Object params[] = { objValue };
		try {
			setMethod.invoke(obj, params);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void setProperty(Object obj, String propName, Object[] values) {
		String prop = "set" + propName.substring(0, 1).toUpperCase()
				+ propName.substring(1);
		Method setMethod = null;
		Method[] ms = obj.getClass().getMethods();
		for (int i = 0; i < ms.length; i++) {
			Method m = ms[i];
			if (m.getName().equals(prop)) {
				setMethod = m;
				break;
			}
		}
		if (setMethod == null)
			return;
		try {
			setMethod.invoke(obj, values);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static Method getMethodByName(Object obj, String method) {
		Method setMethod = null;
		Method[] ms = obj.getClass().getMethods();
		for (int i = 0; i < ms.length; i++) {
			Method m = ms[i];
			if (m.getName().equalsIgnoreCase(method)) {
				setMethod = m;
				break;
			}
		}
		return setMethod;
	}
}
